package com.likuicat.picture_ddd.domain.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.likuicat.picture_ddd.domain.user.constant.UserConstant;
import com.likuicat.picture_ddd.domain.user.entity.User;
import com.likuicat.picture_ddd.domain.user.repository.UserRepository;
import com.likuicat.picture_ddd.domain.user.service.UserDomainService;
import com.likuicat.picture_ddd.domain.user.valueobject.UserRoleEnum;
import com.likuicat.picture_ddd.infrastructure.exception.BusinessException;
import com.likuicat.picture_ddd.infrastructure.exception.ErrorCode;
import com.likuicat.picture_ddd.infrastructure.exception.ThrowUtils;
import com.likuicat.picture_ddd.interfaces.dto.user.UserQueryRequest;
import com.likuicat.picture_ddd.interfaces.vo.user.LoginUserVO;
import com.likuicat.picture_ddd.interfaces.vo.user.UserVO;
import com.likuicat.picture_ddd.shared.auth.StpKit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
* @author fc3379757631
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2025-05-04 15:13:06
*/
@Service
@Slf4j
public class UserDomainServiceImpl implements UserDomainService {

    @Resource
    private UserRepository userRepository;

    /**
     * 用户注册
     * @param userAccount
     * @param password
     * @param checkPassword
     * @return
     */
    @Override
    public long userRegister(String userAccount, String password, String checkPassword) {
        //2.账号重复
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        long count = userRepository.getBaseMapper().selectCount(queryWrapper);
        ThrowUtils.throwIf(count > 0,ErrorCode.PARAMS_ERROR,"账号已存在");
        //3.密码加密
        String encryptPassword = getEncryptPassword(password);
        //4.插入
        try {
            User user = new User();
            user.setUserAccount(userAccount);
            user.setUserPassword(encryptPassword);
            user.setUserName("用户" + userAccount);
            user.setUserAvatar(UserConstant.DEFAULT_USER_AVATAR);
            user.setUserRole(UserRoleEnum.USER.getValue());
            user.setUserProfile("暂无");
            boolean save = userRepository.save(user);
            ThrowUtils.throwIf(!save,ErrorCode.SYSTEM_ERROR,"运行时异常");
            //5.返回用户id
            return user.getId();
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"运行时异常");
        }
    }

    @Override
    public LoginUserVO userLogin(String userAccount, String password, HttpServletRequest request) {
        //2.查询用户是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);
        queryWrapper.eq("userPassword",getEncryptPassword(password));
        User user = userRepository.getBaseMapper().selectOne(queryWrapper);
        ThrowUtils.throwIf(user == null,ErrorCode.PARAMS_ERROR,"用户账号或密码错误");
        //3.用户登录态存入Session
        request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,user);
        // 存入Sa-Token
        StpKit.SPACE.login(user.getId());
        StpKit.SPACE.getSession().set(UserConstant.USER_LOGIN_STATE,user);
        //4.返回
        return getUserToLoginUserVO(user);
    }

    /**
     * 获取当前登录用户
     * @param request
     * @return
     */
    @Override
    public User getLoginUser(HttpServletRequest request) {
        User currentUser = (User)request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        ThrowUtils.throwIf(currentUser == null || currentUser.getId() == null,ErrorCode.NOT_LOGIN_ERROR);
        //查询数据库，若缓存未更新直接返回，得到错误结果
        //获取用户信息能不用缓存就不用
        User loginUser = userRepository.getById(currentUser.getId());
        ThrowUtils.throwIf(loginUser == null,ErrorCode.NOT_LOGIN_ERROR);
        return loginUser;
    }

    /**
     * 用户注销
     * @param request
     * @return
     */
    @Override
    public boolean userLogout(HttpServletRequest request) {
        //判断是否登录
        Object attribute = request.getSession().getAttribute(UserConstant.USER_LOGIN_STATE);
        User user = (User)attribute;
        ThrowUtils.throwIf(user == null,ErrorCode.NOT_LOGIN_ERROR);
        //移除登录态
        request.getSession().removeAttribute(UserConstant.USER_LOGIN_STATE);
        return true;
    }

    /**
     * 加密密码
     * @param password
     * @return
     */
    @Override
    public String getEncryptPassword(String password) {
        //盐值
        final String SALT = UserConstant.SALT;
        return DigestUtils.md5DigestAsHex((SALT + password).getBytes());
    }

    /**
     * 返回脱敏用户LoginUserVO
     * @param user
     * @return
     */
    @Override
    public LoginUserVO getUserToLoginUserVO(User user){
        if (user == null) {
            return null;
        }
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtil.copyProperties(user,loginUserVO);
        return loginUserVO;
    }

    /**
     * 返回脱敏用户UserVO
     * @param user
     * @return
     */
    @Override
    public UserVO getUserToUserVO(User user) {
        if (user == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtil.copyProperties(user,userVO);
        return userVO;
    }

    /**
     * 返回脱敏UserVO集合类
     * @param userList
     * @return
     */
    @Override
    public List<UserVO> getUserVOList(List<User> userList) {
        //判空
        if(CollUtil.isEmpty(userList)){
            return new ArrayList<>();
        }
        return userList.stream().map(this::getUserToUserVO).collect(Collectors.toList());
    }

    /**
     * 将查询请求转化为QueryWrapper
     * @param userQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<User> getUserQueryWrapper(UserQueryRequest userQueryRequest) {
        if(userQueryRequest == null){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        Long id = userQueryRequest.getId();
        String userName = userQueryRequest.getUserName();
        String userAccount = userQueryRequest.getUserAccount();
        String userProfile = userQueryRequest.getUserProfile();
        String userRole = userQueryRequest.getUserRole();
        String sortField = userQueryRequest.getSortField();
        String sortOrder = userQueryRequest.getSortOrder();

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ObjUtil.isNotNull(id),"id", id);
        queryWrapper.like(StrUtil.isNotBlank(userName),"userName",userName);
        queryWrapper.like(StrUtil.isNotBlank(userAccount),"userAccount",userAccount);
        queryWrapper.like(StrUtil.isNotBlank(userProfile),"userProfile",userProfile);
        queryWrapper.eq(StrUtil.isNotBlank(userRole),"userRole",userRole);
        queryWrapper.orderBy(StrUtil.isNotEmpty(sortField), sortOrder.equals("ascend"), sortField);
        return queryWrapper;
    }


    @Override
    public Boolean removeById(Long id) {
        return userRepository.removeById(id);
    }

    @Override
    public boolean updateById(User user) {
        return userRepository.updateById(user);
    }

    @Override
    public User getById(long id) {
        return userRepository.getById(id);
    }

    @Override
    public Page<User> page(Page<User> userPage, QueryWrapper<User> queryWrapper) {
        return userRepository.page(userPage, queryWrapper);
    }

    @Override
    public List<User> listByIds(Set<Long> userIdSet) {
        return userRepository.listByIds(userIdSet);
    }

    @Override
    public boolean save(User user) {
        return userRepository.save(user);
    }
}




